#include "EventLoopThread.h"
#include "Channel.h"
#include "Condition.h"
#include "MutexLock.h"
#include "thread.h"
#include "utils.h"
#include <cassert>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>

using namespace monsoon;

namespace droneswarm
{
    EventLoopThread::EventLoopThread()
        : loop_( NULL )
        , exiting_( false )
        , thread_( std::bind( &EventLoopThread::threadFunc, this ) )
        , mutex_()
        , cond_( mutex_ )
    {
        
    }

    EventLoopThread::~EventLoopThread()
    {
        exiting_ = true;
        if ( loop_ != NULL )
        {
            loop_->quit();
            thread_.join();
        }
    }

    //开启事件循环
    EventLoop *EventLoopThread::startLoop()
    {
        //首先判断线程是否没有启动,只有没有启动才能继续运行
        CondPanic( !thread_.started(), "thread already start!" );
        //只有执行start代码才会真正的创建线程并执行
        thread_.start();
        {
            MutexLockGuard lock( mutex_ );
            //因为线程初始化时，将ThreadFunc绑定到了线程中，线程执行时会执行ThreadFunc并创建EventLoop
            //所以需要等待创建完成在传递出去。
            while ( loop_ == NULL )
            {
                //如果为空，则阻塞等待。
                cond_.wait();
            }
        }
        return loop_;
    }

    //线程执行函数
    void EventLoopThread::threadFunc()
    {

        //首先创建事件循环实例
        EventLoop loop;
        {
            MutexLockGuard lock( mutex_ );
            loop_ = &loop;
            //通知等待的线程，loop实例已经创建
            cond_.notify();
        }

        // loop循环是在线程中执行的
        //循环开启
        loop.loop();
        //循环结束后，loop_需要置为null。
        loop_ = NULL;
    }
}  // namespace droneswarm